
;======================================================================
;获取指定索引文本数据位置
Static_Text_Get_Item_Data_Addr
    LDA <FC_Data_Count
    STA <FC_Data_Index_L
    LDA #$00
    STA <FC_Data_Index_H
    
    ASL <FC_Data_Index_L
    ROL <FC_Data_Index_H

    LDA #LOW(Static_Text_Index)
    CLC
    ADC <FC_Data_Index_L
    STA <FC_Data_Addr_L
    
    LDA #HIGH(Static_Text_Index)
    ADC <FC_Data_Index_H
    STA <FC_Data_Addr_H

    LDY #$00
    LDA [FC_Data_Addr_L],Y
    PHA
    INY 
    LDA [FC_Data_Addr_L],Y
    STA <FC_Data_Addr_H
    PLA
    STA <FC_Data_Addr_L
    RTS

;======================================================================
;初始化静态文本
Static_Text_Init
    LDA #$00
    STA <FC_Data_Count

    ;单条文本写入
.Write_Item
    
    ;获取文本数据地址
    JSR Static_Text_Get_Item_Data_Addr
    
    LDA PPU_STATUS
    LDA #$00
    STA PPU_CTRL
    
    ;没有内容则结束
    LDA <FC_Data_Addr_L
    ORA <FC_Data_Addr_H
    BEQ .End
    
    ;获取文本居中符号
    LDY #$00
    LDA [FC_Data_Addr_L],Y
    PHA
    
    ;获取文本位置高位
    LDY #$02
    LDA [FC_Data_Addr_L],Y
    STA <FC_Data_Temp_H
    
    ;获取文本位置低位
    LDY #$01
    LDA [FC_Data_Addr_L],Y
    STA <FC_Data_Temp_L
    
    PLA
    STA <FC_Data_Index_L
    LDA <FC_Data_Index_L
    BEQ .Write_PPU_Addr
    AND #STATIC_TEXT_VERTIVAL
    BEQ .Write_PPU_Mode
    
    ;PPU垂直写入
    LDA #$04
    STA PPU_CTRL
    
    ;PPU模式检查
.Write_PPU_Mode
    LDA <FC_Data_Index_L
    AND #STATIC_TEXT_CENTER
    BEQ .Write_PPU_Addr
    
.Write_PPU_Center
    ;获取文本长度
    LDY #$03
    LDA [FC_Data_Addr_L],Y
    STA <FC_Data_Index_L
    
    ;计算文本两边空余多少字符(每行32个字符, 减去显示文本长度后的剩余长度 / 2 = 当前行居中显示起始位置)
    LDA #$20
    SEC
    SBC <FC_Data_Index_L
    LSR A
    STA <FC_Data_Index_L
    
    ;计算文本居中位置
    LDA <FC_Data_Temp_L
    AND #$E0
    CLC
    ADC <FC_Data_Index_L
    STA <FC_Data_Temp_L
    
.Write_PPU_Addr
    LDA <FC_Data_Temp_H
    STA PPU_ADDRESS
    LDA <FC_Data_Temp_L
    STA PPU_ADDRESS
    
    LDY #$03
    LDA [FC_Data_Addr_L],Y
    TAX
    INY

    ;写入文本内存
    
.Write_Data
    STY <FC_Data_Char_Index
    LDA [FC_Data_Addr_L],Y
    
    ;小写转大写
    CONVERT_TO_UPPERCASE
    
    STA <FC_Data_Temp
    JSR Convert_Static_Tile
    BCS .Write_Char
    ;字符映射
    .IF CHAR_MAPPING_ENABLE
    TYA
    PHA
    
    LDY <FC_Data_Temp
    LDA Char_Mapping_Data,Y
    STA <FC_Data_Temp
    
    PLA
    TAY
    .ENDIF

.Write_Char
    LDA <FC_Data_Temp
    STA PPU_DATA
    INY
    DEX
    BNE .Write_Data

.Continue
    INC <FC_Data_Count
    JMP .Write_Item
    
.End
    RTS
    
;======================================================================
Convert_Static_Tile
    LDA <FC_Data_Char_Index
    SEC
    SBC #$04
    STA <FC_Data_Char_Index
    LDA <FC_Data_Temp
    CMP #' '
    BNE .End
    TYA
    PHA
    LDA <FC_Data_Temp_H
    PHA
    LDA <FC_Data_Temp_L
    PHA
    
    LDA <FC_Data_Temp_L
    CLC
    ADC #LOW(Nametable_Data)
    STA <FC_Data_Temp_L
    LDA <FC_Data_Temp_H
    AND #$03
    ADC #HIGH(Nametable_Data)
    STA <FC_Data_Temp_H
    
    LDA <FC_Data_Temp_L
    CLC
    ADC <FC_Data_Char_Index
    STA <FC_Data_Temp_L
    LDA <FC_Data_Temp_H
    ADC #$00
    STA <FC_Data_Temp_H
    
    LDY #$00
    LDA [FC_Data_Temp_L],Y
    STA <FC_Data_Temp
    PLA
    STA <FC_Data_Temp_L
    PLA
    STA <FC_Data_Temp_H
    PLA
    TAY
    SEC
    RTS
.End
    CLC
    RTS

;======================================================================
;写入文本PPU位置
Set_Text_Item_Pos
    LDA <FC_Page_Item_Index
    ASL A
    TAY
    LDA Game_Name_Pos + 1,Y
    STA FC_PPU_Buf_Addr,X
    INX
    LDA Game_Name_Pos,Y
    STA FC_PPU_Buf_Addr,X
    INX
    RTS

;======================================================================
;清除一条文本
Page_Text_Item_Clear
    LDX FC_PPU_Buf_Count
    
    ;获取上一页节目索引
    LDA <FC_Page_Last_Index
    CLC
    ADC <FC_Page_Item_Index
    BCS .End            ;最大节目索引超过255, 不处理
    
    CMP #GAME_COUNT - 1 ;与最大节目索引比较
    BCC .Item_Clear     ;小于最大节目索引
    BEQ .Item_Clear     ;等于最大节目索引
    BNE .End            ;大于最大节目索引
    
.Item_Clear
    ;写入清除模式
    LDA #PPU_WRITE_MODE_CNT_LINE
    STA FC_PPU_Buf_Addr,X
    INX
    
    ;写入文本PPU位置
    JSR Set_Text_Item_Pos
    
    ;写入文本长度
    LDA #$00
    STA <FC_Data_Index_H
    LDA <FC_Page_Last_Index
    CLC
    ADC <FC_Page_Item_Index
    STA <FC_Data_Index_L
    
    ;索引左移 1 位
    ASL <FC_Data_Index_L
    ROL <FC_Data_Index_H
    
    ;得到节目名列表起始地址(节目名列表 + 索引)
    LDA #LOW(Game_Name_Index)
    CLC
    ADC <FC_Data_Index_L
    STA <FC_Data_Addr_L
    LDA #HIGH(Game_Name_Index)
    ADC <FC_Data_Index_H
    STA <FC_Data_Addr_H
    
    LDY #$00
    LDA [FC_Data_Addr_L],Y
    PHA
    INY
    LDA [FC_Data_Addr_L],Y
    STA <FC_Data_Addr_H
    PLA
    STA <FC_Data_Addr_L
    
    ;得到文本长度
    LDY #$00
    LDA [FC_Data_Addr_L],Y
    STA <FC_Data_Count
    STA FC_PPU_Buf_Addr,X
    INX
    
    LDA <FC_Page_Item_Index
    ASL A
    TAY
    LDA Game_Name_Pos,Y
    CLC
    ADC #LOW(Nametable_Data)
    STA <FC_Data_Addr_L
    INY
    LDA Game_Name_Pos,Y
    AND #$03
    ADC #HIGH(Nametable_Data)
    STA <FC_Data_Addr_H
    
    LDY #$00
.Write_Item_Data
    LDA [FC_Data_Addr_L],Y
    STA FC_PPU_Buf_Addr,X
    INX
    INY
    DEC <FC_Data_Count
    BNE .Write_Item_Data
.End
    STX FC_PPU_Buf_Count
    RTS

;======================================================================
;写入一条文本
Page_Text_Item_Write
    LDX FC_PPU_Buf_Count

    ;获取当前页节目索引
    LDA <FC_Page_Cur_Index
    CLC
    ADC <FC_Page_Item_Index
    BCS .End            ;最大节目索引超过255, 不处理
    
    CMP #GAME_COUNT - 1 ;与最大节目索引比较
    BCC .Item_Write     ;小于最大节目索引
    BEQ .Item_Write     ;等于最大节目索引
    BNE .End            ;大于最大节目索引
    
.Item_Write
    ;写入行模式
    LDA #PPU_WRITE_MODE_CNT_LINE
    STA FC_PPU_Buf_Addr,X
    INX
    
    ;写入文本PPU位置
    JSR Set_Text_Item_Pos
    
    ;写入文本长度
    LDA #$00
    STA <FC_Data_Index_H
    LDA <FC_Page_Cur_Index
    CLC
    ADC <FC_Page_Item_Index
    STA <FC_Data_Index_L
    
    ;索引左移 1 位
    ASL <FC_Data_Index_L
    ROL <FC_Data_Index_H
    
    ;得到节目名列表起始地址(节目名列表 + 索引)
    LDA #LOW(Game_Name_Index)
    CLC
    ADC <FC_Data_Index_L
    STA <FC_Data_Addr_L
    LDA #HIGH(Game_Name_Index)
    ADC <FC_Data_Index_H
    STA <FC_Data_Addr_H
    
    LDY #$00
    LDA [FC_Data_Addr_L],Y
    PHA
    INY
    LDA [FC_Data_Addr_L],Y
    STA <FC_Data_Addr_H
    PLA
    STA <FC_Data_Addr_L
    
    LDY #$00
    LDA [FC_Data_Addr_L],Y
    STA <FC_Data_Count
    STA FC_PPU_Buf_Addr,X
    INX
    INY
.Write_Item_Data
    STY <FC_Data_Char_Index
    LDA [FC_Data_Addr_L],Y
    
    ;小写转大写
    CONVERT_TO_UPPERCASE
    
    STA <FC_Data_Temp
    JSR Convert_Bgk_Tile
    BCS .Write_Char
    
    ;字符映射
    .IF CHAR_MAPPING_ENABLE
    TYA
    PHA
    
    LDA <FC_Data_Temp
    TAY
    LDA Char_Mapping_Data,Y
    STA <FC_Data_Temp
    
    PLA
    TAY
    .ENDIF
    
.Write_Char
    LDA <FC_Data_Temp
    STA FC_PPU_Buf_Addr,X
    INX
    INY
    DEC <FC_Data_Count
    BNE .Write_Item_Data
.End
    STX FC_PPU_Buf_Count
    RTS

;======================================================================
Convert_Bgk_Tile
    LDA <FC_Data_Temp
    CMP #' '
    BNE .End
    DEC <FC_Data_Char_Index
    TYA
    PHA
    
    ;得到命名表数据地址
    LDA #LOW(Nametable_Data)
    STA <FC_Data_Temp_L
    LDA #HIGH(Nametable_Data)
    STA <FC_Data_Temp_H
    
    LDA <FC_Page_Item_Index
    ASL A
    TAY
    LDA Game_Name_Pos,Y
    CLC
    ADC <FC_Data_Temp_L
    STA <FC_Data_Temp_L
    
    INY
    LDA Game_Name_Pos,Y
    AND #$03
    ADC <FC_Data_Temp_H
    STA <FC_Data_Temp_H
    
    ;得到字符位置数据
    LDA <FC_Data_Temp_L
    CLC
    ADC <FC_Data_Char_Index
    STA <FC_Data_Temp_L
    LDA <FC_Data_Temp_H
    ADC #$00
    STA <FC_Data_Temp_H
    
    LDY #$00
    LDA [FC_Data_Temp_L],Y
    STA <FC_Data_Temp
    PLA
    TAY
    SEC
    RTS
.End
    CLC
    RTS
